/* Copyright (c) 2006 by M Aamir Maniar 
 * 
 * Permission is hereby granted, free of charge, to any person obtaining 
 * a copy of this software and associated documentation files (the 
 * "Software"), to deal in the Software without restriction, including 
 * without limitation the rights to use, copy, modify, merge, publish, 
 * distribute, sublicense, and/or sell copies of the Software, and to 
 * permit persons to whom the Software is furnished to do so, subject to 
 * the following conditions:
 * 
 * The above copyright notice and this permission notice shall be 
 * included in all copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 * */

namespace Generic.Utils
{
    using System;
    using System.Collections.Generic;
    using System.Text;
    using System.Runtime.Serialization;

    /// <summary>
    /// Represents the generic <see cref="Exception&lt;T&gt;"/> class 
    /// which allows to supply generic tag along with the exception.
    /// </summary>
    /// <typeparam name="T">The type of generic tag.</typeparam>
    [global::System.Serializable]
    public class Exception<T> : Exception
        where T : Exception, new()
    {
        #region public Exception()
        /// <summary>
        /// Initializes a new instance of the <see cref="Exception&lt;T&gt;"/> class.
        /// </summary>
        public Exception() { }
        #endregion

        #region public Exception(string message)
        /// <summary>
        /// Initializes a new instance of the <see cref="Exception&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="message">The message.</param>
        public Exception(string message) : base(message) { }
        #endregion

        #region public Exception(string message, Exception inner)
        /// <summary>
        /// Initializes a new instance of the <see cref="Exception&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="message">The message.</param>
        /// <param name="inner">The inner.</param>
        public Exception(string message, Exception inner) : base(message, inner) { }
        #endregion

        #region protected Exception(SerializationInfo info, StreamingContext context)
        /// <summary>
        /// Initializes a new instance of the <see cref="Exception&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo"></see> that holds the serialized object data about the exception being thrown.</param>
        /// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext"></see> that contains contextual information about the source or destination.</param>
        /// <exception cref="T:System.Runtime.Serialization.SerializationException">The class name is null or <see cref="P:System.Exception.HResult"></see> is zero (0). </exception>
        /// <exception cref="T:System.ArgumentNullException">The info parameter is null. </exception>
        protected Exception(SerializationInfo info, StreamingContext context) : base(info, context) { } 
        #endregion

        #region public Exception(T tag)
        /// <summary>
        /// Initializes a new instance of the <see cref="Exception&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="tag">The tag.</param>
        public Exception(T tag) { _tag = tag; } 
        #endregion

        #region public Exception(T tag, string message)
        /// <summary>
        /// Initializes a new instance of the <see cref="Exception&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="tag">The tag.</param>
        /// <param name="message">The message.</param>
        public Exception(T tag, string message) : base(message) { _tag = tag; } 
        #endregion

        #region public Exception(T tag, string message, Exception inner)
        /// <summary>
        /// Initializes a new instance of the <see cref="Exception&lt;T&gt;"/> class.
        /// </summary>
        /// <param name="tag">The tag.</param>
        /// <param name="message">The message.</param>
        /// <param name="inner">The inner.</param>
        public Exception(T tag, string message, Exception inner) : base(message, inner) { _tag = tag; } 
        #endregion

        #region public T Tag
        private T _tag;
        /// <summary>
        /// Gets or sets the tag. This generic tag can be 
        /// handy incase of some quick exception with extra 
        /// information is required.
        /// </summary>
        /// <value>The tag.</value>
        public T Tag
        {
            get { return _tag; }
            set { _tag = value; }
        } 
        #endregion
    }
}